home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / disk / cdrom / cdlib.lha / cdlib.c next >
Encoding:
C/C++ Source or Header  |  2000-04-16  |  7.8 KB  |  280 lines

  1. /*++
  2.  
  3. File: cdlib.c
  4.  
  5.     Read the AsimTunes (which is the AsimCDFS CDDA player) disc library.
  6.  
  7.     Creates listings on stdout and can also export track and program data
  8.     in the widely used "ID files" format.
  9.  
  10. --*/
  11.  
  12. char *pcVersion = "$VER: CdLib 1.1 (16.04.2000) "
  13.                   "by Wilhelm Nöker <wnoeker@t-online.de>";
  14.  
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18.  
  19.  
  20. typedef int BOOL;
  21. #define FALSE   0
  22. #define TRUE    1
  23.  
  24. char *pcIdxF = "AsimCDFS_Buffer:CD_Library.index";
  25. char *pcDatF = "AsimCDFS_Buffer:CD_Library.data";
  26. char *pcTrkF = "CdLib_Temp_Trk";
  27. char *pcPrgF = "CdLib_Temp_Prg";
  28. FILE *fpIdx, *fpDat;
  29.  
  30.  
  31.  
  32. /*++
  33.  
  34. Function: Help()
  35.  
  36.     Print command line usage.
  37.  
  38. --*/
  39.  
  40. void Help()
  41.     {
  42.     fprintf( stderr, "CdLib: list the AsimCDFS audio disc library\n" );
  43.     fprintf( stderr, "Usage:\n  CdLib [options] >listfile\n" );
  44.     fprintf( stderr, "where options are\n" );
  45.     fprintf( stderr, "  -d    list discs\n" );
  46.     fprintf( stderr, "  -t    list tracks\n" );
  47.     fprintf( stderr, "  -v/-V verbose track listing\n" );
  48.     fprintf( stderr, "  -u    show user settings\n" );
  49.     fprintf( stderr, "  -i    create ID files (in the current dir.)\n" );
  50.     }
  51.  
  52.  
  53.  
  54. /*++
  55.  
  56. Function: DiscInfo()
  57.  
  58.     Print information about one CD in the database.
  59.  
  60. Arguments:
  61.  
  62.     lRecord - record number, zero-based
  63.  
  64.     nFlags - option bitmap: 1=discs, 2=tracks, 4=user settings,
  65.         8=create an ID (and PR) file
  66.  
  67.     nLevel - level of track listing verbosity: 1=add album, 2=add artist
  68.  
  69. Return Value:
  70.  
  71.     FALSE, if no such record exists.
  72.  
  73. --*/
  74.  
  75. BOOL DiscInfo( long lRecord, int nFlags, int nLevel )
  76.     {
  77.     long lOffset, lTotal, lPos = 0, lThirdPos=0, lFirstPos=0;
  78.     int i;
  79.     char caName[ 50 ], caTitle[ 50 ], caTrack[ 50 ], caBuf[ 50 ];
  80.     unsigned char baPrg[ 256 ];
  81.     unsigned char cMode, cTrks, cMin, cSec, cTick, cFlags, cPos;
  82.     int nSkipped = 0;
  83.     FILE *fpTrk = NULL, *fpPrg = NULL;
  84.  
  85.     if( fseek( fpIdx, 4 * lRecord, SEEK_SET ) != 0 )
  86.         return FALSE;
  87.     if( fread( &lOffset, sizeof( long ), 1, fpIdx ) < 1 )
  88.         return FALSE;
  89.     fseek( fpDat, lOffset, SEEK_SET );
  90.     fread( caName, sizeof( char ), 41, fpDat );
  91.     fread( caTitle, sizeof( char ), 34, fpDat );
  92.     cFlags = fgetc( fpDat );
  93.     cTrks = fgetc( fpDat );
  94.     cMin  = fgetc( fpDat );
  95.     cSec  = fgetc( fpDat );
  96.     cTick  = fgetc( fpDat );
  97.     lTotal = (cMin * 60 + cSec) * 75 + cTick;
  98.     fseek( fpDat, 9, SEEK_CUR );
  99.     cMode = fgetc( fpDat );
  100.     if( nFlags & 1 )
  101.         {                       /* print information about the disc */
  102.         if( nFlags & 4 )
  103.             {
  104.             if( cFlags & 1 )
  105.                 printf( "A%c/%c%c ", " PRO"[ cMode ],
  106.                         (cFlags & 2) ? 'S':'s', (cFlags & 4) ? 'R':'r' );
  107.             else
  108.                 printf( "      " );
  109.             }
  110.         printf( "%2d:%02d ", cMin, cSec );
  111.         printf( "%2d%23s ", cTrks, "" );
  112.         printf( "%-30s %s", caTitle, caName );
  113.         putchar( '\n' );
  114.         }
  115.     if( nFlags & 8 )
  116.         {
  117.         fpPrg = fopen( pcPrgF, "w" );
  118.         memset( baPrg, 0, sizeof( baPrg ) );
  119.         fpTrk = fopen( pcTrkF, "w" );
  120.         fprintf( fpTrk, "%s\n%s\n", caName, caTitle );
  121.         }
  122.     if( nFlags & (2 | 8) )
  123.         {                       /* examine ther track entries */
  124.         fseek( fpDat, 34, SEEK_CUR );
  125.         for( i = 0; i < cTrks; i++ )
  126.             {
  127.             fread( caTrack, sizeof( char ), 27, fpDat );
  128.             lPos = fgetc( fpDat );
  129.             lPos = (lPos << 8) | fgetc( fpDat );
  130.             lPos = (lPos << 8) | fgetc( fpDat );
  131.             cMin  = fgetc( fpDat );
  132.             cSec  = fgetc( fpDat );
  133.             cTick  = fgetc( fpDat );
  134.             fseek( fpDat, 4, SEEK_CUR );
  135.             cPos   = fgetc( fpDat );
  136.             cFlags = fgetc( fpDat );
  137.             fseek( fpDat, 15, SEEK_CUR );
  138.             if( nFlags & 2 )
  139.                 {
  140.                 if( nFlags & 4 )
  141.                     {
  142.                     printf( ( cPos <= cTrks ) ? "%3d" : "   ", cPos );
  143.                     printf( " %c ", (cFlags & 1) ? 'x':' ' );
  144.                     }
  145.                 printf( "%2d:%02d ", cMin, cSec );
  146.                 printf( "%-25s ", caTrack );
  147.                 if( nLevel > 0 )
  148.                     printf( "%-30s %s", caTitle, (nLevel > 1) ? caName : "" );
  149.                 putchar( '\n' );
  150.                 }
  151.             if( nFlags & 8 )
  152.                 {
  153.                 fprintf( fpTrk, "%s\n", caTrack );  /* add an ID line */
  154.                 if( cMode == 3 )        /* i.e. "play in order" */
  155.                     {
  156.                     if( cPos <= cTrks ) /* prepare an ordered list */
  157.                         baPrg[ cPos ] = i + 1;
  158.                     }
  159.                 else
  160.                     {
  161.                     if( cFlags & 1 )
  162.                         nSkipped++;
  163.                     else                /* add a prg item */
  164.                         fputc( i + 1, fpPrg );
  165.                     }
  166.                 if( i == 0 )
  167.                     lFirstPos = lPos;
  168.                 if( i == 2 )
  169.                     lThirdPos = lPos;
  170.                 }
  171.             }
  172.         }
  173.     if( nFlags & 8 )
  174.         {                       /* cleanup for the ID file(s) */
  175.         if( cMode == 3 )        /* dump the playlist that we built */
  176.             for( i = 0; i < 256; i++ )
  177.                 if( baPrg[ i ] != 0 )
  178.                     fputc( baPrg[ i ], fpPrg );
  179.         lFirstPos = 0x96;       /* seems wrong, but it works */
  180.         sprintf( caBuf, "ID%02d%06lX%06lX", cTrks,
  181.                 lThirdPos - lFirstPos, lTotal - lFirstPos );
  182.         fprintf( stderr, "%ld: %s, %-30s\r", lRecord, caBuf, caTitle );
  183.         fflush( stderr );
  184.         /* Close and rename the temp files. */
  185.         fclose( fpTrk );
  186.         rename( pcTrkF, caBuf );
  187.         strncpy( caBuf, "PR", 2 );
  188.         fclose( fpPrg );
  189.         if( cMode == 3 || nSkipped > 0 )
  190.             rename( pcPrgF, caBuf );
  191.         }
  192.  
  193.     return TRUE;
  194.     }
  195.  
  196.  
  197.  
  198. /*++
  199.  
  200. Function: main()
  201.  
  202.     Uses unix style command line parsing, see Help() for explanation
  203.     of the expected parameters.
  204.  
  205. --*/
  206.  
  207. int main( int argc, char *argv[] )
  208.     {
  209.     long lDiscs, lIdx;
  210.     int nFlags = 0, nLevel = 0;
  211.     char *pcTemp;
  212.  
  213.     while( --argc )
  214.         {
  215.         argv++;
  216.         if( *argv[ 0 ] == '-' )
  217.             switch( argv[ 0 ][ 1 ] )
  218.                 {
  219.                 case 'd':
  220.                     nFlags |= 1;
  221.                     break;
  222.                 case 't':
  223.                     nFlags |= 2;
  224.                     break;
  225.                 case 'u':
  226.                     nFlags |= 4;
  227.                     break;
  228.                 case 'i':
  229.                     nFlags |= 8;
  230.                     break;
  231.                 case 'v':
  232.                     nLevel = 1;
  233.                     break;
  234.                 case 'V':
  235.                     nLevel = 2;
  236.                     break;
  237.                 default:
  238.                     Help();
  239.                     return 5;
  240.                 }
  241.         else
  242.             {
  243.             Help();
  244.             return 5;
  245.             }
  246.         }
  247.  
  248.     /* Try to open the database files in the current directory first, */
  249.     /* use absolute pathname only if that fails. */
  250.     pcTemp = strchr( pcIdxF, ':' );
  251.     fpIdx = pcTemp ? fopen( pcTemp + 1, "rb" ) : NULL;
  252.     if( fpIdx == NULL )
  253.         fpIdx = fopen( pcIdxF, "rb" );
  254.     if( fpIdx == NULL )
  255.         {
  256.         fprintf( stderr, "file not found: \"%s\"\n", pcIdxF );
  257.         return 10;
  258.         }
  259.     pcTemp = strchr( pcDatF, ':' );
  260.     fpDat = pcTemp ? fopen( pcTemp + 1, "rb" ) : NULL;
  261.     if( fpDat == NULL )
  262.         fpDat = fopen( pcDatF, "rb" );
  263.     if( fpDat == NULL )
  264.         {
  265.         fprintf( stderr, "file not found: \"%s\"\n", pcDatF );
  266.         return 10;
  267.         }
  268.     fseek( fpIdx, 0, SEEK_END );
  269.     lDiscs = ftell( fpIdx ) / 4;
  270.     printf( "%ld audio CDs listed\n", lDiscs );
  271.     if( nFlags > 0 )
  272.         for( lIdx = 0; lIdx < lDiscs; lIdx++ )
  273.             DiscInfo( lIdx, nFlags, nLevel );
  274.  
  275.     fclose( fpIdx );
  276.     fclose( fpDat );
  277.  
  278.     return 0;
  279.     }
  280.